package org.jing.core.lang.data;

import org.jing.core.lang.JingException;

import java.util.concurrent.atomic.AtomicLong;

/**
 * Description: 序列 <br>
 *
 * @author bks <br>
 * @since 2024-07-08 <br>
 */
public class Sequence extends AtomicLong {
    private final long minValue;

    private final long maxValue;

    public Sequence(long maxValue) {
        super(0);
        if (maxValue < 0) {
            throw new JingException("max must >= min");
        }
        this.minValue = 0;
        this.maxValue = maxValue;
    }

    public Sequence(long minValue, long maxValue) {
        super(minValue);
        if (maxValue < minValue) {
            throw new JingException("max must >= min");
        }
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    public Sequence(long initialValue, long minValue, long maxValue) {
        super(initialValue);
        if (maxValue < minValue) {
            throw new JingException("max must >= min");
        }
        if (initialValue > maxValue || initialValue < minValue) {
            throw new JingException("initial must between min and max");
        }
        this.minValue = minValue;
        this.maxValue = maxValue;
    }

    public long next() {
        for (;;) {
            long current = get();
            long next = (current >= maxValue) ? minValue : current + 1;
            if (compareAndSet(current, next)) {
                return next;
            }
        }
    }
}
